package com.oauth.twitter.server.service;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.gwtwidgets.server.spring.ServletUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;

import com.oauth.common.server.util.OAuthStringUtil;
import com.oauth.logging.OAuthLogger;
import com.oauth.service.application.ApplicationService;
import com.oauth.service.generic.beans.OAuthServiceBean;
import com.oauth.service.global.beans.OAuthAccessToken;
import com.oauth.service.global.beans.OAuthRequestToken;
import com.oauth.twitter.client.beans.Tweet;
import com.oauth.twitter.client.beans.TwitterUser;
import com.oauth.twitter.server.conf.TwitterInfoBean;
import com.oauth.twitter.server.conf.TwitterOAuthConfig;
import com.oauth.twitter.server.utils.TwitterConversionUtil;

@Service
public class TwitterServiceImpl implements TwitterService {

	private OAuthLogger logger = OAuthLogger.getLogger(this.getClass());
	@Autowired
	private ApplicationService applicationService;

	@Autowired
	private TwitterOAuthConfig twitterOAuthConfig;

	@Autowired
	TwitterInfoBean twitterInfoBean;

	private Twitter getTwitter(OAuthAccessToken pAccessToken) {
		return new TwitterFactory().getOAuthAuthorizedInstance(twitterOAuthConfig.getConsumerKey(),
				twitterOAuthConfig.getConsumerSecret(), new AccessToken(pAccessToken.getToken(),
						pAccessToken.getTokenSecret()));
	}

	private Twitter getTwitter() {
		return new TwitterFactory().getOAuthAuthorizedInstance(twitterOAuthConfig.getConsumerKey(),
				twitterOAuthConfig.getConsumerSecret());
	}

	public OAuthRequestToken getRequestToken() throws Exception {
		Twitter twitter = getTwitter();
		RequestToken requestToken = null;
		requestToken = twitter.getOAuthRequestToken(twitterOAuthConfig.getCallBackUrl());
		return new OAuthRequestToken(requestToken.getToken(), requestToken.getTokenSecret(),
				requestToken.getAuthorizationURL());
	}

	private OAuthAccessToken getAccessTokenFromDB(Long pMemberId) throws Exception {
		OAuthServiceBean token = applicationService.getToken(pMemberId, twitterInfoBean.getKey());
		if (token != null) {
			return new OAuthAccessToken(token.getAccessToken(), token.getAccessTokenSecret());
		}
		return null;
	}

	@Override
	public OAuthAccessToken getAccessToken(OAuthRequestToken requestToken) throws Exception {
		HttpServletRequest request = ServletUtils.getRequest();
		String verifier = request.getParameter("oauth_verifier");
		if (OAuthStringUtil.isBlank(verifier)) {
			throw new Exception("Verifier not found");
		}
		AccessToken accessToken = getTwitter().getOAuthAccessToken(requestToken.getToken(),
				requestToken.getTokenSecret(), verifier);
		return new OAuthAccessToken(accessToken.getToken(), accessToken.getTokenSecret());

	}

	@Override
	public Tweet updateTweet(String pTweetText, Long pMemberId) throws Exception {
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		Twitter twitter = getTwitter(accessToken);
		Status updateTweet = twitter.updateStatus(pTweetText);
		return TwitterConversionUtil.convertToTweet(updateTweet);
	}

	@Override
	public List<Tweet> getTweets(Long pMemberId) throws Exception {
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		Twitter twitter = getTwitter(accessToken);
		ResponseList<Status> userTimeline = twitter.getHomeTimeline();
		return TwitterConversionUtil.convertToTweets(userTimeline);
	}

	@Override
	public TwitterUser getUserInfo(Long pMemberId) throws Exception {
		OAuthAccessToken accessToken = getAccessTokenFromDB(pMemberId);
		Twitter twitter = getTwitter(accessToken);
		User user = twitter.showUser(twitter.getId());
		return TwitterConversionUtil.convertToUser(user);

	}
}
